package net.tribal.comic.controllers

import net.tribal.comic.entities.User
import net.tribal.comic.entities.Comic
import net.tribal.comic.entities.Page
import net.tribal.comic.entities.AlterPage
import net.tribal.comic.entities.Comment
import net.tribal.comic.entities.Rate


class UserController {
	def userService
	
	/**
     *  Les accions 'delete', 'save', 'updateProfile', 'updateFile' i 'updatePassword' nom�s accepten peticions POST
     */
    static allowedMethods = [save:"POST", updateProfile:"POST", updateFile:"POST", updatePassword:"POST", delete:"POST"]
                             
                             
	/**
	 * Acci� per defecte
	 */
    def index = { redirect(action: "list", params: params) }
	
	
	/**
	 * Commuta entre entre el modes de visionat "Coverflow" i "Llistat" 
	 */
 	def changeView = {
 		session['userViewMode'] = (session['userViewMode'] == 'list') ? "flow" : "list"
 		redirect(controller:"user", action:"list", params: params)
 	}
	
                             
    /**
     * Mostra els usuaris
     * 
     * Si el usuari autenticat t� perfil d'administrador mostra el usuaris actius i no actius,
     * sino nom�s els usuaris actius
     * 
     * La cerca podr� ser filtrada per alias segons el valor del camp 'searchAjax'
     * 
     * return GSP
     *  render - /user/listContent
     *  render - /user/list
     */
    def list = {
        params.max = Math.min(params.max ? params.max.toInteger() : 10,  100)
        def list = userService.getActiveUsers(params.max, params.offset?.toInteger(), params.sort, params.order, session['user']?.admin, params?.searchAjax)
		
		if(params.searchAjax != null){
	        //	La cerca es as�ncrona
			render(template:"/user/listContent", model:[userInstanceList:list['data'], userInstanceTotal:list['count']])
			return
		} 
	
        // La cerca es s�ncrona
        render(view:"/user/list", model:[userInstanceList:list['data'], userInstanceTotal:list['count']])
        return 
    }


	/**
     * Mostra la pantalla per crear un usuari
     * 
     * return GSP
     *  render - /user/create
     */
    def create = {
        def userInstance = new User()
        userInstance.properties = params
        render(view:"/user/create", model:[userInstance: userInstance])
        return
    }


	/**
     * Desa un usuari
     * 
     * return GSP
     *  redirect /user/show
     *  render - /user/create
     */
    def save = {
		def instance = userService.add( new User(params), request.getFile('file'), params.password, params.repeatPassword, params.termsOfUse )
    	
		if(!instance.hasErrors()){
			if(session.user){
				flash.message = "flash.user.created"
	            flash.args = [instance.alias]
			}else{
				session.user = instance
				flash.message = "flash.user.created.welcome"
	            flash.args = [instance.alias]
			}
			
			redirect(controlelr:"user", action: "show", id: instance.id)
			return
		}
		
		render(view:"/user/create", model:[userInstance: instance])
		return
    }

	
	/**
     * Mostra un usuari
     * 
     * retun
     * 	redirect - /user/list
     *  render - /user/show
     */
    def show = {
        def userInstance = User.get(params.id)
        
        if (!userInstance) {
            flash.message = "flash.user.not.found"
            flash.args = [params.id]
            redirect(controller:"user", action:"list")
            return
        }
        
        def userSession = User.get(session.user?.ident())
    	def yourOldRate = userService.getRateFromUser ( userInstance, userSession )

    	render(view:"/user/show", model:[userInstance: userInstance, yourRate:yourOldRate])
        return
    }


	/**
     * M�tode que mostra les dades personals d'un usuari
     * 
     * retun
     * 	redirect - /user/list
     *  render - /user/editProfile
     * 
     */
    def editProfile = {
		def userInstance = User.get(params.id)
		def userSession = User.get(session.user.id)
		
        if (!userInstance) {
            flash.message = "flash.user.not.found"
            flash.args = [params.id]
            redirect(controller:"user", action:"list")
            return
        }

		render (view:"/user/editProfile", model:[userInstance: userInstance])
		return
    }


	/**
     * M�tode que mostra la p�gina per canviar la contrasenya
     * 
     * retun
     * 	redirect - /user/list
     *  render - /user/editPassword
     */
	def editPassword = {
		def userInstance = User.get(params.id)
		def userSession = User.get(session.user.id)
		
        if (!userInstance) {
            flash.message = "flash.user.not.found"
            flash.args = [params.id]
            redirect(controller:"user", action:"list")
            return
        }
		
		render (view:"/user/editPassword", model:[userInstance: userInstance])
		return
    }


	/**
	 * M�tode que mostra la p�gina per canviar l'imatge del usuari
	 * 
	 * retun
     * 	redirect - /user/list
     *  render - /user/editFile
	 */
	def editFile = {
		def userInstance = User.get(params.id)
		def userSession = User.get(session.user.id)
		
        if (!userInstance) {
            flash.message = "flash.user.not.found"
            flash.args = [params.id]
            redirect(controller:"user", action:"list")
            return
        }

		render (view:"/user/editFile", model:[userInstance: userInstance])
		return
    }


	/**
	 * Actualitza les dades del perfil
	 * 
	 * retun
	 *  redirect - /user/show
     * 	redirect - /user/show
     *  render - /user/editProfile
	 */
	def updateProfile = {
		def userInstance = User.get(params.id)
		
		if ( !userInstance ) {
			flash.message = "flash.user.not.found"
            flash.args = [params.id]
            redirect(controller:"user", action:"list")
            return
		}
		
		userInstance.properties = params
		userInstance = userService.changeProfile ( userInstance )
		
		if ( userInstance.hasErrors() ) {
			render(view:"/user/editProfile", model:[userInstance: userInstance])
			return
    	}

		flash.message = "flash.user.updated"
        flash.args = [params.id]
        redirect(controller:"user", action:"show", id:userInstance.id)
        return
	}


	/**
	 * Actualitza els password d'un usuari
	 * 
	 * retun
	 *  redirect - /user/list
	 * 	redirect - /user/show
	 *  render - /user/editProfile
	 */
	def updatePassword = {
		def userInstance = User.get (params.id)
		
		if ( !userInstance ) {
			flash.message = "flash.user.not.found"
            flash.args = [params.id]
            redirect(controller:"user", action:"list")
            return
		}

		userInstance = userService.changePassword ( userInstance, params.version, params.password, params.repeatPassword )
		
		if ( userInstance.hasErrors() ) {
			render(view:"/user/editPassword", model:[userInstance: userInstance])
			return
    	}
	
		flash.message = "flash.user.updated"
        flash.args = [params.id]
        redirect(controller:"user", action:"show", id:userInstance.id)
    	return
	}


	/**
	 * Actualitza els password d'un usuari
	 * 
	 * retun
	 *  redirect - /user/list
	 * 	redirect - /user/show
	 *  render - /user/editFile
	 */
	def updateFile = {
		def userInstance = User.get(params.id)
		
		if ( !userInstance ) {
			flash.message = "flash.user.not.found"
            flash.args = [params.id]
            redirect(controller:"user", action:"list")
            return
		}

		userInstance = userService.changeFile ( userInstance, request.getFile('file') )

		
		userInstance.errors.each(){print it}
		
		if ( userInstance.hasErrors() ) {
			render(view:"/user/editFile", model:[userInstance: userInstance])
			return
    	}
		
		flash.message = "flash.user.updated"
        flash.args = [params.id]
        redirect(controller:"user", action:"show", id:userInstance.id)
		return
	}
	

	/**
	 * Elimina un usuari
	 * 
	 * retun
	 *  redirect - /user/list
	 * 	redirect - /user/show
	 */
    def delete = {
		def instance = User.get(params.id)
		
		if ( !instance ) {
			flash.message = "flash.user.not.found"
			flash.args = [params.id]
			redirect(controller:"user", action:"list")
			return
		}
		
		instance = userService.delete( instance )
		
		if (!instance.hasErrors()) {
			// Si es borra l'usuari autenticat, es desautentica
			if(instance.id == session.user.id){
				session.invalidate()
				flash.message = "flash.user.deleted.bye"
	            flash.args = [params.id]
	            redirect(controller:"user", action:"list")
	            return
			}else{
				flash.message = "flash.user.deleted"
	            flash.args = [params.id]
	            redirect(controller:"user", action:"list")
	            return
			}
		}
		
        redirect(controller:"user", action:"show", id: instance.id)
		return
    }
    

	/**
	 * Desactiva un usuari
	 * 
	 * retun
	 *  redirect - /user/list
	 * 	redirect - /user/show
	 */
    def disable = {
		def instance = User.get(params.id)
		
		if ( !instance ) {
			flash.message = "flash.user.not.found"
			flash.args = [params.id]
			redirect(controller:"user", action:"list")
			return
		}
		
		instance.disabled = false
		def result = userService.changeProfile( instance )

		if(!result.hasErrors()){
			flash.message = "flash.user.updated"
			flash.args = [params.id]
            redirect(controller:"user", action:"show", id:instance.id)
			return
		}
			
		redirect(controller:"user", action:"show", id:instance.id)
		return
    }


	/**
	 * Activa un usuari
	 * 
	 * retun
	 *  redirect - /user/list
	 * 	redirect - /user/show
	 */
    def enable = {
		def instance = User.get(params.id)
		
		if ( !instance ) {
			flash.message = "flash.user.not.found"
			flash.args = [params.id]
			redirect(controller:"user", action:"list")
			return
		}
		
		instance.disabled = true
		def result = userService.changeProfile( instance )

		if(!result.hasErrors()){
			flash.message = "flash.user.updated"
			flash.args = [params.id]
            redirect(controller:"user", action:"show", id:instance.id)
			return
		}
			
		redirect(controller:"user", action:"show", id:instance.id)
		return
    }
	

	/**
	 * Busquem totes les aportacions del usuari
	 * Si l'usuari autenticat es administrador, veu totes les aportacions, 
	 * si no, nom�s les actives
	 *  
	 * return
	 *  Map - comics
	 *  Map - p�gines
	 *  Map - p�gines alternatives
	 *  String - nom del usuari
	 */
    def contributions = {
		def user = User.get(params.id)
		def admin = User.get(session.user?.id)?.admin
		
		if(user){		
			def comics = []
			user.comics?.each { 
				if(admin || (!admin && !it.disabled)){ comics << it }
			}
			
			def pages = []
			user.pages?.each { 
				if(admin || (!admin && !it.disabled)){ pages << it }
	   		}
			
			def alterPages = []
			user.alterPages?.each { 
				if(admin || (!admin && !it.disabled)){ alterPages << it }
			}
			
			render(view:"/user/contributions", model:[comics:comics, pages:pages, alterPages:alterPages, 'userName':user.alias, userId:user.ident()])
			return
		}
		
		redirect(controller="user", action="list", params:params)
		return
	}
	

	/**
	 * M�tode que afegeix un comic a la llista de comics favorits d'un usuari
	 * 
	 * retun
	 *  render - /comic/show
	 */
	def addToFavorites = {
		def comic = Comic.get(params.id)
		def user = User.get(session.user.id)
		
		user.addToFavoriteComics(comic)
		if(user.hasErrors()){
			comic.errors.rejectValue('','error.comic.addToFavorites')
			render(view:"/comic/show", model:[comicInstance:comic])
			return	
		}
		
		flash.message = "flash.comic.addToFavorites"
		flash.args = [params.id]
        render(view:"/comic/show", model:[comicInstance:comic])
		return
	}
	
	
	/**
	 * Mostra el comics favorits del usuari
	 * 
	 * retun
	 *  render - /comic/list
	 */
	def showFavorites = {
		params.max = Math.min(params.max ? params.max.toInteger() : 10,  100)
		
		def li = []
		def user = User.get(params.id)
		def admin = session.user?.admin
		user.favoriteComics?.each { 
			if(admin || (!admin && !it.disabled)){
				li << it 
			}
		}
		
		render(view:"/comic/list", model:[comicInstanceList:li, comicInstanceTotal:li.size()])
	}
	
	
	/**
	 * Mostra les tasques d'administraci�
	 * 
	 * retun
	 *  render - /adminTask/list
	 */
    def adminTasks = {
    	render( view:"/adminTask/list")
    }
	
	
	/**
	 * Sol�licita moderaci� d'un usuari
	 * 
	 * retun
	 *  render - /adminTask/listModerationRequests
	 */
	def moderationRequests = {
		def results = [:]
		results['comics'] = Comic.findAllByModerationRequest(true)
		results['pages'] = Page.findAllByModerationRequest(true)
		results['alterPages'] = AlterPage.findAllByModerationRequest(true)
		
		render ( view:"/adminTask/listModerationRequests", model:[list:results])
	}
	
	
	/**
	 * Afegeix un vot a un usuari
	 * Si es la primera vegada que un usuari vota a un usuari en concret, afegeix un vot
	 * si no, actualiza el vot
	 * 
	 * retun
	 *  render - /rate/rate
	 */
	def rate = {
		def user = User.get(params.id)
		def userSession = User.get(session.user.ident())
		
		if(userService.rate(params.rating, user, userSession)){
			//	Es puntua correctament
	        flash.message = "flash.rate.saved"
			render(template: "/rate/rateCustom", model:[instance: user, from:'user', yourRate:params.rating])
			return
		}else{
			//	Error al puntuar
			user.errors.rejectValue('','error.rate.fault')
			render(template: "/rate/rateCustom", model:[instance: user, from:'user', yourRate:params.rating])
			return
		}
	}
	
	
	/**
	 * Afegeig un comentari a un usuari
	 * 
	 * return
	 *  - render: /comment/create
	 *  - redirect: /user/comments
	 */
	def addComment = {
		def comment = new Comment(params)
		comment.createdBy = session['user']
		                            
		//	Si t� errors, mostrem la pantalla de creaci� d'un comentari.
        if (comment.hasErrors() ) {
    		render(template:"/comment/create", model:[commentInstance:comment, commentToName:params.commentToName, commentToId:params.commentToId])
    		return
        }
        
        def user = User.get(params.commentToId.toLong())
		user.addToUserComments(comment)
        
        flash.message = "flash.comment.saved"
        redirect(controller:"user", action:"comments", params:[commentToId:params.commentToId])
        return
	}
	
	
	/**
	 * Mostra els comentaris d'un usuari
	 * 
	 * retun
	 *  render - /comment/list
	 */
	def comments = {
        params.max = Math.min(params.max ? params.max.toInteger() : 10,  100)
        
		def list = userService.getUserComments(params.max, params.offset?.toInteger(), params.sort, params.order, session['user']?.admin, params?.commentToId)
	    
        render(template:"/comment/list", model:[commentInstanceList: list['data'], commentInstanceTotal:list['count'], commentToName:'user', commentToId:params.commentToId])
        return
    }
}
